home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-PPC / SOFTIRQ.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  2KB  |  111 lines

  1. #ifndef __ASM_SOFTIRQ_H
  2. #define __ASM_SOFTIRQ_H
  3.  
  4. #include <asm/atomic.h>
  5. #include <asm/hardirq.h>
  6.  
  7. extern unsigned int local_bh_count[NR_CPUS];
  8.  
  9. #define get_active_bhs()    (bh_mask & bh_active)
  10. #define clear_active_bhs(x)    atomic_clear_mask((x),&bh_active)
  11.  
  12. extern inline void init_bh(int nr, void (*routine)(void))
  13. {
  14.     bh_base[nr] = routine;
  15.     atomic_set(&bh_mask_count[nr], 0);
  16.     bh_mask |= 1 << nr;
  17. }
  18.  
  19. extern inline void remove_bh(int nr)
  20. {
  21.     bh_mask &= ~(1 << nr);
  22.     wmb();
  23.     bh_base[nr] = NULL;
  24. }
  25.  
  26. extern inline void mark_bh(int nr)
  27. {
  28.     set_bit(nr, &bh_active);
  29. }
  30.  
  31. #ifdef __SMP__
  32. /*
  33.  * The locking mechanism for base handlers, to prevent re-entrancy,
  34.  * is entirely private to an implementation, it should not be
  35.  * referenced at all outside of this file.
  36.  */
  37. extern atomic_t global_bh_lock;
  38. extern atomic_t global_bh_count;
  39.  
  40. extern void synchronize_bh(void);
  41.  
  42. static inline void start_bh_atomic(void)
  43. {
  44.     atomic_inc(&global_bh_lock);
  45.     synchronize_bh();
  46. }
  47.  
  48. static inline void end_bh_atomic(void)
  49. {
  50.     atomic_dec(&global_bh_lock);
  51. }
  52.  
  53. /* These are for the IRQs testing the lock */
  54. static inline int softirq_trylock(int cpu)
  55. {
  56.     if (!test_and_set_bit(0,&global_bh_count)) {
  57.         if (atomic_read(&global_bh_lock) == 0) {
  58.             ++local_bh_count[cpu];
  59.             return 1;
  60.         }
  61.         clear_bit(0,&global_bh_count);
  62.     }
  63.     return 0;
  64. }
  65.  
  66. static inline void softirq_endlock(int cpu)
  67. {
  68.     local_bh_count[cpu]--;
  69.     clear_bit(0,&global_bh_count);
  70. }
  71.  
  72. #else /* __SMP__ */
  73.  
  74. extern inline void start_bh_atomic(void)
  75. {
  76.     local_bh_count[smp_processor_id()]++;
  77.     barrier();
  78. }
  79.  
  80. extern inline void end_bh_atomic(void)
  81. {
  82.     barrier();
  83.     local_bh_count[smp_processor_id()]--;
  84. }
  85.  
  86. /* These are for the irq's testing the lock */
  87. #define softirq_trylock(cpu)    (local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
  88. #define softirq_endlock(cpu)    (local_bh_count[cpu] = 0)
  89. #define synchronize_bh()    do { } while (0)
  90.  
  91. #endif /* __SMP__ */
  92.  
  93. /*
  94.  * These use a mask count to correctly handle
  95.  * nested disable/enable calls
  96.  */
  97. extern inline void disable_bh(int nr)
  98. {
  99.     bh_mask &= ~(1 << nr);
  100.     atomic_inc(&bh_mask_count[nr]);
  101.     synchronize_bh();
  102. }
  103.  
  104. extern inline void enable_bh(int nr)
  105. {
  106.     if (atomic_dec_and_test(&bh_mask_count[nr]))
  107.         bh_mask |= 1 << nr;
  108. }
  109.  
  110. #endif
  111.